#include <functional>
#include <algorithm>
#include <cstring>
#include "packet.h"
#include <sstream>
#include "packet.h"

namespace igslib
{
	IPacketManager* CPacketManager::instance = 0;
	IPacketManager* CPacketManager::GetInstance() 
	{
		if ( instance == 0 )
		{
			instance = new CPacketManager();
		}
		return instance ;
	}

    CPacket::CPacket():
        buf(count,'\0')
    {
    }
    int CPacket::GetHeaderID()
    {
        int rtn = -1;
        rtn = buf[header];
        return rtn;
    }
    void CPacket::SetHeaderID(const int& value)
    {
        buf[header] = static_cast<char>(value);
    }
    void CPacket::SetData(const std::vector<char>& value)
    {
        auto hv = buf[header];
        buf.clear();
        buf.push_back(hv);
        buf.push_back(value.size());
        for(auto& each:value)
        {
            buf.push_back(each);
        }
	    //RK3288 packet using
	    char packetcksum=Getu8Checksum(buf);	
		buf.push_back(packetcksum);
		
		
    }
    std::vector<char> CPacket::GetData()
    {
        std::vector<char> rtn;
        for ( int i = data ; i < buf.size()-1 ; ++i )
        {
            rtn.push_back(buf[i]);
        }
        return rtn;
    }
    char CPacket::Getu8Checksum(const std::vector<char>& value)
    {
        char rtn = 0;
        for(auto& each:value)
        {
            rtn += static_cast<int>(each);
        }
        return rtn;
    }
    char CPacket::GetSelfu8Checksum()
    {
        return buf.back();
    }
    int CPacket::GetUniqueID(const std::vector<char>& value)
    {
        int rtn = 0;
        auto tmp = value;
        std::hash<std::vector<char>*> hash_fn;
        size_t h = hash_fn(&tmp);
        rtn = static_cast<int>(h);
        return rtn;
    }
    int CPacket::GetSelfUniqueID()
    {
        return GetUniqueID(buf);
    }
    std::vector<char> CPacket::GetWholePacket()
    {
        std::vector<char> rtn;
        rtn = buf;
        return rtn;
    }
    int CPacket::ImportRawData(const char* value)
    {
        int rtn = 0;
        char* addr = const_cast<char*>(value);
        buf.clear();
        buf.push_back(addr[rtn++]);
        //printf("%s/header=0x%02x,rtn=%d\n",__func__,buf[header],rtn);
        buf.push_back(addr[rtn++]);
        //printf("%s/length=0x%02x,rtn=%d\n",__func__,buf[length],rtn);
        //printf("%s/data=",__func__);
        for ( int i = 0 ; i < buf[length] ; ++i )
        {
            buf.push_back(addr[rtn++]);
            //printf("0x%02x,",buf[data+i]);
        }
        //printf("rtn=%d\n",rtn);
		
		//RK3288 packet using
	    char packetcksum=Getu8Checksum(buf);	
		 buf.push_back(packetcksum);
        return rtn;
    }

    IPacket* CPacketManager::NewPacket()
    {
        IPacket* rtn = NULL;
        rtn = new CPacket();
        cpns.insert(rtn);
        return rtn;
    }
    std::vector<IPacket*> CPacketManager::NewPacketsWithRawData(const char* value,const int& length)
    {
        std::vector<IPacket*> rtn;
        char* buf = const_cast<char*>(value);
        int inx = 0;

        while(inx < length)
        {
            IPacket* p = new CPacket();
            inx += p->ImportRawData(&buf[inx]);
            //printf("%s> inx=%d,strlen(value)=%d\n",__func__,inx,strlen(value));
            cpns.insert(p);
            rtn.push_back(p);
        }
        return rtn;
    }
}

extern "C"{
	igslib::IPacketManager* GetPacketManagerInstance()
	{
        igslib::IPacketManager* rtn = NULL;
        rtn = igslib::CPacketManager::GetInstance();
		return rtn;
	}
}

